package com.quectel.util.mongo;

import com.mongodb.client.result.UpdateResult;
import com.quectel.util.client.mongo.MongoBaseModel;
import com.quectel.util.client.mongo.MongoClient;
import lombok.Getter;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.Collection;
import java.util.List;
import java.util.Map;


/**
 * @author caolu
 * @email louis.cao@quectel.com
 */
public class MongodbUtils {

    @Getter
    private static MongoClient defaultClient;

    private MongodbUtils() {

    }

    /**
     * 默认的客户端
     *
     * @param defaultClient
     */
    public static void setDefaultClient(MongoClient defaultClient) {
        MongodbUtils.defaultClient = defaultClient;
    }

    /**
     * 是否已经初始化配置
     *
     * @return
     */
    public static boolean isReady() {
        return MongodbUtils.defaultClient != null;
    }


    public static <T extends MongoBaseModel> T add(T basePojo) {
        return defaultClient.add(basePojo);
    }

    public static <T extends MongoBaseModel> T add(T basePojo, String collectionName) {
        return defaultClient.add(basePojo, collectionName);
    }

    public static <T extends MongoBaseModel> T insert(T objectToSave, String collectionName) {
        return defaultClient.insert(objectToSave, collectionName);
    }

    public static <T extends MongoBaseModel> Collection<T> insertMany(Collection<T> batchToSave, String collectionName) {
        return defaultClient.insertMany(batchToSave, collectionName);
    }

    public static <T extends MongoBaseModel> UpdateResult update(T basePojo, Update update, String collectionName) {
        return defaultClient.update(basePojo, update, collectionName);
    }

    public static UpdateResult update(Query query, Update update, String collectionName) {
        return defaultClient.update(query, update, collectionName);
    }

    public static void delete(Long id, String collectionName) {
        defaultClient.delete(id, collectionName);
    }

    public static <T extends MongoBaseModel> void delete(T basePojo, String collectionName) {
        defaultClient.delete(basePojo, collectionName);
    }

    public static void remove(Query query, String collectionName) {
        defaultClient.remove(query, collectionName);
    }

    public static <T extends MongoBaseModel> T findOne(Long id, String collectionName, Class<T> clazz) {
        return defaultClient.findOne(id, collectionName, clazz);
    }

    public static <T extends MongoBaseModel> T findOneData(Class<T> clazz, Query query, String collectionName) {
        return defaultClient.findOneData(clazz, query, collectionName);
    }

    public static <T extends MongoBaseModel> List<T> findAll(Class<T> clazz, String collectionName) {
        return defaultClient.findAll(clazz, collectionName);
    }

    public static <T extends MongoBaseModel> List<T> find(Query query, Class<T> clazz, String collectionName) {
        return defaultClient.find(query, clazz, collectionName);
    }

    /**
     * 分页方法
     *
     * @param query
     * @param pageNo   从0开始
     * @param pageSize
     * @param sort     null不排序
     * @param clazz
     * @return
     */
    public static <T extends MongoBaseModel> List<T> page(Query query,
                                                          int pageNo,
                                                          int pageSize,
                                                          Sort sort,
                                                          Class<T> clazz, String collectionName) {
        return defaultClient.page(query, pageNo, pageSize, sort, clazz, collectionName);
    }


    public static long count(Query query, String collectionName) {
        return defaultClient.count(query, collectionName);
    }

    /**
     * @param criteria
     * @param collectionName
     * @param field          $deviceDto._id 或者 deviceDto.id
     * @return
     */
    public static int countDistinct(Criteria criteria, String collectionName, String field) {

        return defaultClient.countDistinct(criteria, collectionName, field);
    }

    public static <T extends MongoBaseModel> T max(Query query, Class<T> clazz, String collectionName, String fieldName) {
        return defaultClient.max(query, clazz, collectionName, fieldName);
    }

    public static <T extends MongoBaseModel> T min(Query query, Class<T> clazz, String collectionName, String fieldName) {

        return defaultClient.min(query, clazz, collectionName, fieldName);
    }

    public static <O> AggregationResults<O> aggregate(Aggregation aggregation, String collectionName, Class<O> var2) {
        return defaultClient.aggregate(aggregation, collectionName, var2);
    }

    /**
     * @param criteria
     * @param field          $deviceDto._id 或者 deviceDto.id
     * @param collectionName
     * @return 需要注意key可能为 null
     */
    public static Map<String, Integer> groupCountBy(Criteria criteria, String field, String collectionName) {
        return defaultClient.groupCountBy(criteria, field, collectionName);
    }

    public static <T extends MongoBaseModel> Collection<T> queryList(Query query,
                                                                     Class<T> clazz, String collectionName) {
        return defaultClient.queryList(query, clazz, collectionName);
    }

    public static long total(Query query, String collectionName) {
        return defaultClient.total(query, collectionName);
    }

    public static <T extends MongoBaseModel> T queryOne(Query query, Class<T> entityClass, String collectionName) {
        return defaultClient.queryOne(query, entityClass, collectionName);
    }

}

























